﻿using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.Linq;

namespace XRM.ActiveDirectoryService
{
    public static class Helper
    {
        public static IEnumerable<DirectoryEntry> FilterByOU (this PrincipalSearchResult<Principal> searchResult, string[] ouNames)
        {
            foreach ( var de in searchResult.Select( result => (DirectoryEntry)result.GetUnderlyingObject() ) )
            {
                if (!IsActive(de))
                    continue;

                var distinguishedName = (string)de.Properties["distinguishedName"].Value;
                if ( ouNames != null && !ouNames.Any( distinguishedName.Contains ) )
                    continue;

                yield return de;
            }
        }
        public static List<ADUser> ToAdUsers(this PrincipalSearchResult<Principal> searchResult, string[] ouNames)
        {
            return searchResult.FilterByOU( ouNames ).Select( de => de.ToAdUser()).ToList();
        }

        public static ADUser ToAdUser( this DirectoryEntry de )
        {
            return new ADUser
            {
                FirstName = GetFirstName( (string)de.Properties["givenName"].Value ),
                LastName = (string)de.Properties["sn"].Value,
                MiddleName = GetMiddleName( (string)de.Properties["displayName"].Value ),
                AccountName = (string)de.Properties["samAccountName"].Value,
                Post = (string)de.Properties["title"].Value,
                Department = (string)de.Properties["department"].Value,
            };
        }

        private static string GetFirstName(string value)
        {
            return value == null ? null : value.Split( new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries )[0];
        }

        public static bool IsActive( this DirectoryEntry de )
        {
            if ( de.NativeGuid == null ) 
                return false;
            var flags = (int)de.Properties["userAccountControl"].Value;
            return !Convert.ToBoolean( flags & 0x0002 );
        }

        private static string GetMiddleName(string displayName)
        {
            if ( displayName == null )
                return null;
            var fio = displayName.Split( new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries );
            return fio.Length == 3 ? fio[2] : null;
        }
    }
}
